import type { ObjectDirective } from 'vue';

interface DraggableBindingValue {
  onDragEnd?: () => void;
}

const draggable: ObjectDirective<HTMLElement, DraggableBindingValue> = {
  
  mounted(el, binding) {
    let currentPosX = 0;
    let currentPosY = 0;
    let startPosX = 0;
    let startPosY = 0;

    const onMouseDown = (event: MouseEvent) => {
      currentPosX = event.clientX;
      currentPosY = event.clientY;
      startPosX = el.offsetLeft;
      startPosY = el.offsetTop;
      document.addEventListener('mousemove', onMouseMove);
      document.addEventListener('mouseup', onMouseUp);
      event.preventDefault(); // 防止选中文本时干扰拖动
    };

    const onMouseMove = (event: MouseEvent) => {
      const dx = event.clientX - currentPosX;
      const dy = event.clientY - currentPosY;
      const x = startPosX + dx;
      const y = startPosY + dy;
      if (x >= 0 && y >= 0) {
        el.style.left = x + 'px';
        el.style.top = y + 'px';
      }
    };

    const onMouseUp = (event: MouseEvent) => {
      document.removeEventListener('mousemove', onMouseMove);
      document.removeEventListener('mouseup', onMouseUp);
      const rect = el.getBoundingClientRect();
      const top = rect.top;
      const left = rect.left;
      if (top <= 0 || left <= 0) {
        binding.value?.onDragEnd?.();
      }
    };

    el.addEventListener('mousedown', onMouseDown);
  },

  unmounted(el) {
    el.removeEventListener('mousedown', onMouseDown);
  },
};

export default draggable